<template>
  <div class="search-container">
    <!-- 搜索页面头部 -->
    <div class="search-header">
      <!-- 后退按钮 -->
      <van-icon
        name="arrow-left"
        color="white"
        size="0.48rem"
        class="goback"
        @click="$router.go(-1)"/>
      <!-- 搜索组件 -->
      <van-search
        v-model="keyword"
        placeholder="请输入搜索关键词"
        background="#007BFF"
        shape="round"
        v-focus
        @input="handleSearch"
        @search="goto(keyword)"
      />
    </div>
    <!-- 搜索建议列表 -->
    <ul
      class="sugg-list"
      v-if="suggList.length">
      <li class="sugg-item"
        v-for="(str, idx) in suggList"
        :key="idx"
        v-html="highlight(str)"
        @click="goto(str)"
        >
      </li>
    </ul>
    <!-- 搜索历史 -->
    <div
      class="search-history"
      v-else>
      <!-- 标题 -->
      <van-cell title="搜索历史">
        <!-- 使用 right-icon 插槽来自定义右侧图标 -->
        <template #right-icon>
          <van-icon
            name="delete"
            class="search-icon"
            @click="handleClear"
          />
        </template>
      </van-cell>
      <!-- 历史列表 -->
      <div class="history-list">
        <span
          class="history-item"
          v-for="(str, idx) in historyList"
          :key="idx"
          @click="goto(str)"
          >{{ str }}</span>
      </div>
    </div>
  </div>
</template>

<script>
// 数据刷新不丢失：
// 前台：cookie/本地存储
// 后台：发请求同步到数据库
import { getSuggListAPI } from '@/api/search'
export default {
  name: 'SearchView',
  data () {
    return {
      keyword: '', // 搜索关键字
      suggList: [], // 联想建议列表
      // 刷新的时候或路由回退的时候从本地取值
      historyList: JSON.parse(localStorage.getItem('history')) || [] // 搜索历史记录
    }
  },
  watch: {
    // 只要调用了7个可以改变数组的方法，会触发watch函数
    historyList (newVal) {
      // 把新值存储到本地
      localStorage.setItem('history', JSON.stringify(newVal))
    }
  },
  methods: {
    // 输入时搜索
    handleSearch () {
      // 这里的timer属性为什么不用再data中声明？
      // 因为timer不需要再标签中展示，并且不需要它的响应式的特性
      // 先关闭上一个延时器
      if (this.timer) clearTimeout(this.timer)
      // 重新开启一个新的延迟器
      this.timer = setTimeout(async () => {
        if (!this.keyword) {
          // 清空联想建议列表
          this.suggList = []
          return
        }
        // 调接口发请求
        const resp = await getSuggListAPI(this.keyword)
        // 保存联想建议列表(把筛选的结果在赋值，舍去没有值的项)
        this.suggList = resp.data.options.filter(str => str)
      }, 500)
    },
    // 搜索建议高亮 = 正则+字符串的替换
    highlight (str) {
      // 根据关键字的内容创建正则对象
      // ig: 正则修饰符，i表示忽略大小写，g表示全局匹配
      const regexp = new RegExp(this.keyword, 'ig')
      // 调用字符串的repalce方法做替换，返回替换结果
      return str.replace(regexp, (match) => `<span style="color:red">${match}</span>`)
    },
    // 跳转
    goto (keyword) {
      // 如果没有关键字，提前结束
      if (!keyword) return
      // 如果关键字不在数组中
      if (!this.historyList.includes(keyword)) {
        // 把关键字push到historyList数组
        this.historyList.push(keyword)
      }
      setTimeout(() => {
        // 跳转至搜索结果页
        this.$router.push(`/search/${keyword}`)
      })
    },
    // 清空
    async handleClear () {
      try {
        // 询问
        await this.$dialog.confirm({
          title: '温馨提示',
          message: '确认清空么?'
        })
        // 点击确定，正常执行try中的后续代码
        this.historyList = []
      } catch (e) {
        // 点击取消执行catch
      }
    }
  }
}
</script>

<style scoped lang="less">
.search-header {
  display: flex;
  align-items: center;
  height: 46px;
  background-color: #007bff;
  overflow: hidden;
  /*后退按钮*/
  .goback {
    padding-left: 14px;
  }
  /*搜索组件*/
  .van-search {
    flex: 1;
  }
}
/*搜索建议列表样式 */
.sugg-list {
  .sugg-item {
    padding: 0 15px;
    border-bottom: 1px solid #f8f8f8;
    font-size: 14px;
    line-height: 50px;
    // 实现省略号的三行代码
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/**搜索历史 */
.search-icon {
  font-size: 16px;
  line-height: inherit;
}

.history-list {
  padding: 0 10px;
  .history-item {
    display: inline-block;
    font-size: 12px;
    padding: 8px 14px;
    background-color: #efefef;
    margin: 10px 8px 0px 8px;
    border-radius: 10px;
  }
}
</style>
